import java.util.List;
import java.util.Random;

public class StrategyManager {

	private int initCash;
	private boolean isBidding;
	private int cash;
	private int handType;
	private int handScore;
	private int position;
	private int round;
	//private int maxPlayers;
	private Random generator;
	private int biddingNumber;
	private int drawingNumber;
	private ActionRecord[] players;
	private int averagePlayerType;
	private int highestBet;
	private int myBet;
	private StrategyContainer container;
	private int myId; 

	// 0 - Big Blind (aka early position if 7+ players)
	// 1 - Middle Position
	// 2 - Cut Off
	// 3 - button & small blind

	StrategyManager() {
		generator = new Random();
		myBet = 0;
		isBidding = true;
		container = new StrategyContainer(this);
		round=1;
		
	}

	private void updateAveragePlayerType() {
		int types[] = { 0, 0, 0, 0, 0 };

		for (ActionRecord p : players) {
			if (p != null)
				types[p.evaluatePlayerType()]++;
		}

		int max = types[0];

		for (int i = 0; i < types.length; i++) {
			if (types[i] > max)
				max = types[i];
		}

		averagePlayerType = max;
	}

	public boolean isBidding() {
		return isBidding;
	}

	public void setHighestBet(int highestBet) {
		this.highestBet = highestBet;
	}

	public void bet(int amount) {
		cash = cash - amount;
		myBet = myBet + amount;
	}

	public boolean canCheck() {
		if (myBet == highestBet)
			return true;
		else
			return false;
	}

	public void changePhase(int number) {
		if (isBidding) {
			isBidding = false;
			biddingNumber = number;
		} else {
			isBidding = true;
			drawingNumber = number;
		}
	}

	public void setCash(int cash) {
		this.cash = cash;
	}

	public void result(int id, int type) {
		if (players[id].countDrawnCards() == 0 && type != 4
				&& players[id].getLastBiddingAction() != 0)
			players[id].bluffed();
	}

	public void setHandType(int type) {
		this.handType = type;
	}

	public int getHandType() {
		return handType;
	}

	public void setHandScore(int score) {
		this.handScore = score;
	}

	public void setPosition(int position) {
		this.position = position;
	}

	public String play() {
		/*
		 * if(biddingNumber==1){ switch(handType){ case 2:
		 * if(position<2||handScore<3) return "*F"; //ELSE SNOW; break; case 3:
		 * if(handScore<5+position) return "*F" } }
		 */
		
		return container.getStrategy(averagePlayerType).play();

	}

	public String draw() {
		return container.getStrategy(averagePlayerType).draw();

	}

	public int getRound() {
		return round;
	}

	public void nextRound() {
		round++;
		biddingNumber = 1;
		drawingNumber = 0;
		isBidding=true;
		updateAveragePlayerType();
	}

	public int getDrawingNumber() {
		return drawingNumber;
	}

	public int getBiddingNumber() {
		return biddingNumber;
	}

	public int random(int range) {
		return generator.nextInt(range);
	}

	public int getHandScore() {
		return handScore;
	}

	public int getPosition() {
		return position;
	}

	public boolean isBetterHand() {
		for (ActionRecord player : players) {
			if(player!=null && player.hasWinningHand())
				return true;
		}

		return false;
	}

	public int getBetValue(boolean isAgressive) {

		if (isAgressive) {
			if (cash < (highestBet - myBet) + 0.05 * initCash) {
				return -1;
			} else
				return (highestBet - myBet)
						+ (((generator.nextInt(5) + 1) * initCash) / 100);
		} else {
			if (cash < (highestBet - myBet) + 0.03 * initCash) {
				return -1;
			} else
				return (highestBet - myBet)
						+ (((generator.nextInt(3) + 1) * initCash) / 100);
		}

	}

	public void setup(int maxPlayers, int cash) {

		//this.maxPlayers = maxPlayers;
		this.initCash = cash;

		players = new ActionRecord[maxPlayers];
		for (int i = 0; i < maxPlayers; i++) {
			players[i] = new ActionRecord(this);
		}
		
		players[myId]=null;
	}
	
	public void setId(int id){
		myId=id;
	}

	public void played(int playerId, int action) {
		players[playerId].addBettingAction(action);
	}

	public boolean doIStay() {
		if (cash < (10 * initCash) / 100) {
			return false;
		} else
			return true;
	}

	public void left(int playerId) {
		players[playerId] = null;
	}
}
